using System;
using System.Diagnostics.CodeAnalysis;

namespace InfiniTec.Data
{
    /// <summary>
    /// This class contains the base functionality for a property of an Exchange item.
    /// </summary>
    [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords")]
    public class Property: IPropertyInfo, IEquatable<Property>
    {
        private bool _HasChanged;
        private PropertyStatus _Status;
        private readonly IPropertyDefinition _Definition;

        /// <summary>
        /// If the property was created during a refresh operation, 
        /// this value returns the Http status of that request.
        /// </summary>
        public PropertyStatus Status
        {
            get { return _Status; }
            set { _Status = value; }
        }


        IPropertyDefinition IPropertyInfo.PropertyDefinition { get { return _Definition; } }

        /// <summary>
        /// Returns the full qualifed name of the property.
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return _Definition.Name;
        }

        /// <summary>
        /// Returns true, if the value of the property has changed.
        /// False, otherwise.
        /// </summary>
        public bool HasChanged
        {
            get { return _HasChanged; }
        }

        private Property()
        {
            _Status = PropertyStatus.Ok;
        }

        /// <summary>
        /// Creates a new instance of this class using the specified name.
        /// </summary>
        public Property(IPropertyDefinition propertyDefinition): this()
        {
            if (propertyDefinition == null) throw new ArgumentNullException("propertyDefinition");
            _Definition = propertyDefinition;
        }

        /// <summary>
        internal void SetChanged()
        {
            _HasChanged = true;
        }

        public void ResetChanged()
        {
            _HasChanged = false;
        }

        bool IPropertyInfo.PropertyValueIsNull { get { return false; } }

        object IPropertyInfo.Value { get { throw new NotImplementedException(); } }

        /// <summary>
        /// Clones this instance.
        /// </summary>
        /// <returns></returns>
        public virtual Property Clone()
        {
        	var result = new Property(_Definition) {_Status = _Status, _HasChanged = _HasChanged};

        	return result;
        }


        public bool Equals(Property property)
        {
            if (property == null) return false;
            return Equals(_Definition, property._Definition);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(this, obj)) return true;
            return Equals(obj as Property);
        }

        public override int GetHashCode()
        {
            return _Definition.GetHashCode();
        }
    }
}